feat(effects): split text without motion-plus#383
Conversation
|
✅ Preview deployed: https://blueshift-preview-pr-383.blueshift-gg.workers.dev |
There was a problem hiding this comment.
Pull request overview
This PR removes the motion-plus dependency by introducing an internal text segmentation utility and a reusable reveal-animation hook, then updating the HeadingReveal component to use them.
Changes:
- Added
segmentText()(Intl.Segmenter-based with fallback) to split text into animatable tokens. - Added
useTokenRevealAnimation()to drive the cursor/reveal animation over segmented tokens. - Updated
HeadingRevealto render token<span>s and use the new hook; removedmotion-plusfrom dependencies.
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lib/text/segmentText.ts | New tokenization utility using Intl.Segmenter with a regex-based fallback. |
| src/hooks/useTokenRevealAnimation.ts | New hook that segments text and runs the Motion animation over animatable token elements. |
| src/app/components/HeadingReveal/HeadingReveal.tsx | Refactored to render segmented tokens and delegate animation to the new hook. |
| package.json | Removes motion-plus dependency. |
| pnpm-lock.yaml | Lockfile update reflecting removal of motion-plus. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| shouldAnimate: | ||
| splitBy === "words" | ||
| ? (segment.isWordLike ?? /\S/.test(segment.segment)) | ||
| : /\S/.test(segment.segment), |
There was a problem hiding this comment.
In the Intl.Segmenter path, shouldAnimate uses segment.isWordLike ?? /\S/.test(...). When isWordLike is false (e.g., punctuation tokens like ","), this will mark them as not animating, which can leave punctuation visible while the rest of the text is revealed. To keep behavior consistent with the fallback (and with typical reveal animations), consider basing shouldAnimate on non-whitespace for word splitting as well, or otherwise ensure punctuation is included in the animated targets.
| shouldAnimate: | |
| splitBy === "words" | |
| ? (segment.isWordLike ?? /\S/.test(segment.segment)) | |
| : /\S/.test(segment.segment), | |
| shouldAnimate: /\S/.test(segment.segment), |
| const resolvedSplitBy = splitBy ?? "words"; | ||
|
|
||
| useEffect(() => { | ||
| document.fonts.ready.then(() => { | ||
| if (!containerRef.current) return; | ||
| const { containerRef, tokens, getTokenRef } = useTokenRevealAnimation({ | ||
| text, | ||
| splitBy: resolvedSplitBy, | ||
| locale, |
There was a problem hiding this comment.
This changes the default splitting behavior: previously splitBy defaulted based on the active locale (via useSplitLocaleBy()), but now it always defaults to "words". If this component is used with zh-Hant/zh-Hans content, that can regress the intended character-by-character reveal. Consider restoring the locale-based default (or deriving it from the new locale prop) to preserve prior behavior.
No description provided.